package com.project.erp.model.system;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.apache.struts2.json.annotations.JSON;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.google.common.collect.Lists;
import com.project.erp.model.IdEntity;

@Entity
@Table(name = "TBL_PRIVILEGE")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Privilege extends IdEntity implements Comparable<Privilege>{

	private static final long serialVersionUID = 4162810169030677717L;

	private String name; // 名称
	private String url; // URL地址
	private String external; //可访问资源URL,多个URL用";"隔开
	private String menuType;	 //类型  1:是菜单项,2功能,3,资源
	private Long parentId;   // 父节点ID
	private Long level; // 树的层次
	private Privilege parent; // 父节点
	private List<Role> roles = Lists.newArrayList(); //角色关联对象

	private String text;
	private boolean checked;
	//树形菜单需要这个参数
	private Map<String, String> attributes = new HashMap<String, String>();
	
	// private Set<AcctPrivilege> children = new HashSet<AcctPrivilege>();
	private List<Privilege> children; // 有序的关联对象集合

	@Column(name = "NAME",nullable = true)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	@Column(name = "NAME",nullable = true,updatable=false,insertable=false)
	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	@JSON(name = "tabUrl")
	@Column(name = "URL")
	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	@Column(name = "type",length=1)
	public String getMenuType() {
		return menuType;
	}

	public void setMenuType(String menuType) {
		this.menuType = menuType;
	}

	@Column(name = "EXTERNAL")
	public String getExternal() {
		return external;
	}

	public void setExternal(String external) {
		this.external = external;
	}

	@ManyToOne(fetch = FetchType.LAZY, targetEntity = Privilege.class)
	@JoinColumn(name = "PARENT_ID")
	public Privilege getParent() {
		return parent;
	}

	public void setParent(Privilege parent) {
		this.parent = parent;
		// 设置父节点的时候，将当前节点加入到父节点的孩子列表中
		/*if (parent != null) {
			parent.addChild(this);
		}*/
	}

	public void addChild(Privilege a) {
		if (children == null) {
			children = new ArrayList<Privilege>();
		}
		children.add(a);
	}

	// @OneToMany(mappedBy="parent",fetch=FetchType.EAGER)
	// public Set<AcctPrivilege> getChildren() {
	// return children;
	// }
	// public void setChildren(Set<AcctPrivilege> children) {
	// this.children = children;
	// }

	/**
	 * 双向关联查询树形结构会发出很多sql查询
	 * 
	 * @return
	 */
	// @OneToMany(mappedBy="parent",fetch=FetchType.LAZY)
	// @OrderBy("id ASC")
	@Transient
	public List<Privilege> getChildren() {
		return children;
	}

	public void setChildren(List<Privilege> children) {
		this.children = children;
	}

	@JSON(name="_parentId")
	@Column(name = "PARENT_ID",insertable=false,updatable=false)
	public Long getParentId() {
		return parentId;
	}

	public void setParentId(Long parentId) {
		this.parentId = parentId;
	}
	
	@ManyToMany(mappedBy="privileges",cascade=CascadeType.REFRESH) 
	public List<Role> getRoles() {
		return roles;
	}

	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}

	@Transient
	public Long getLevel() {
		return level;
	}

	public void setLevel(Long level) {
		this.level = level;
	}

	@Transient
	public Map<String, String> getAttributes() {
		return attributes;
	}

	public void setAttributes(Map<String, String> attributes) {
		this.attributes = attributes;
	}
	
	@Transient
	public boolean isChecked() {
		return checked;
	}

	public void setChecked(boolean checked) {
		this.checked = checked;
	}

	@Override
	public int compareTo(Privilege o) {
		if(getId() < o.getId()){
			return -1;
		}else if(getId() > o.getId()){
			return 1;
		}
		return 0;
	}
	
}
